﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CubaLibreBar.Model.Core.Entities;
using CubaLibreBar.Model.Entidades;
using CubaLibreBar.Model.Dados;
using System.Data.SqlClient;
using System.Data.SqlServerCe;

namespace CubaLibreBar.Win.Controles
{
    public partial class CadastroVendas : UserControl
    {

        #region Propriedades

        // lista de produtos da gridview
        List<ProdutosDto> produtos = new List<ProdutosDto>();

        #endregion

        #region Eventos

        public CadastroVendas()
        {
            InitializeComponent();
        }

        private void Vendas_Load(object sender, EventArgs e)
        {
            float val = 0.0f;
            lbTotal.Text = "TOTAL: " + val.ToString("C");
            lbTotal.Visible = true;
            CarregaComboProdutos();
        }

        /// <summary>
        /// EVENTO DE TROCA DE PRODUTOS NO COMBO BOX
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbProdutos_SelectedIndexChanged(object sender, EventArgs e)
        {
            gbDetalhesProduto.Visible = true;
            epProduto.Clear();

            AtualizaEstoque();
            AtualizaDetalhesProdutos();
        }

        /// <summary>
        /// FECHAMENTO DO PEDIDO
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFecharPedido_Click(object sender, EventArgs e)
        {
            if (gvProdutos.Rows.Count > 0)
            {
                DialogResult resultado = MessageBox.Show("Deseja fechar o pedido?", "CubaLibreBar", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

                if (resultado == DialogResult.OK)
                {
                    Vendas venda = new Vendas();
                    venda.DataVenda = DateTime.Now;
                    venda.QuantidadeVenda = GetQuantidade();
                    venda.ValorVenda = GetTotal();

                    VendasDAO.FecharPedido(venda, produtos);
                    RecarregaTela();
                    MessageBox.Show("Venda concluída com sucesso.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show("Nenhum produto foi adicionado a lista, não é possível fechar a venda.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Evento do click do botão Adicionar
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAdicionar_Click(object sender, EventArgs e)
        {
            bool camposValidos = ValidaCampos();

            if (camposValidos)
            {
                int quantidade, estoque = Convert.ToInt32(txtEstoque.Text);
                Produtos produto = (Produtos)cbProdutos.SelectedItem;

                if (Int32.TryParse(txtQuantidade.Text, out quantidade))
                {
                    if (quantidade >= 0 && quantidade <= estoque)
                    {
                        bool achou = produtos.Any(p => p.IdProduto == produto.IdProduto);
                        ProdutosDto produtoDto = new ProdutosDto();

                        if (achou)
                        {
                            produtoDto = (ProdutosDto)produtos.First(p => p.IdProduto == produto.IdProduto);
                            produtos.Remove(produtoDto);

                            produto.QuantidadeProduto += produtoDto.QuantidadeProduto;
                            produtoDto.QuantidadeProduto += quantidade;
                            produtoDto.PrecoVenda += (produto.PrecoVenda * quantidade);
                        }
                        else
                        {
                            produtoDto.IdProduto = produto.IdProduto;
                            produtoDto.NomeProduto = produto.NomeProduto;
                            produtoDto.QuantidadeProduto = quantidade;
                            produtoDto.PrecoVenda = (produto.PrecoVenda * quantidade);
                        }

                        produtos.Add(produtoDto);
                        produto.QuantidadeProduto -= produtoDto.QuantidadeProduto;
                        AtualizaEstoque();
                        CarregaGridProdutos();
                        LimpaCampos();
                        CalculaTotal();
                    }
                    else
                    {
                        MessageBox.Show("A quantidade não pode ser menor que 0 ou maior que o Estoque.", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("O Campo quantidade não aceita letras e caracteres especiais.", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show(this, "Verifique os campos indicados com erro e insira valores válidos.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Evento do botão Remover
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRemover_Click(object sender, EventArgs e)
        {
            if (gvProdutos.CurrentRow != null)
            {
                DialogResult resultado = MessageBox.Show("Deseja deletar o produto " + gvProdutos.CurrentRow.Cells["NomeProduto"].Value
                    , "Delete", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

                if (resultado == DialogResult.OK)
                {
                    int rowIndex = gvProdutos.CurrentRow.Index;
                    int idProduto = Convert.ToInt32(gvProdutos.CurrentRow.Cells["IdProduto"].Value);
                    int quantidade = Convert.ToInt32(gvProdutos.Rows[rowIndex].Cells["QuantidadeProduto"].FormattedValue);

                    foreach (var item in cbProdutos.Items)
                    {
                        Produtos produto = (Produtos)item;
                        if (produto.IdProduto == idProduto)
                        {
                            produto.QuantidadeProduto += quantidade;
                        }
                    }

                    produtos.RemoveAt(rowIndex);
                    CarregaGridProdutos();
                    AtualizaEstoque();
                    CalculaTotal();
                }
            }
        }

        private void txtQuantidade_KeyPress(object sender, KeyPressEventArgs e)
        {
            epQuantidade.Clear();

            if (char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar))
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }

        private void gvProdutos_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex < 0 || e.RowIndex < 0) return; // header clicked

            if (e.ColumnIndex == gvProdutos.Columns["btnDelete"].Index)
            {
                int idProduto = Convert.ToInt32(gvProdutos["IdProduto", e.RowIndex].Value);
                int quantidade = Convert.ToInt32(gvProdutos["QuantidadeProduto", e.RowIndex].Value);

                DialogResult resultado = MessageBox.Show("Deseja remover o produto " + gvProdutos["NomeProduto", e.RowIndex].Value + " do pedido?"
                    , "Delete", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

                if (resultado.Equals(DialogResult.OK))
                {
                    try
                    {
                        foreach (var item in cbProdutos.Items)
                        {
                            Produtos produto = (Produtos)item;
                            if (produto.IdProduto == idProduto)
                            {
                                produto.QuantidadeProduto += quantidade;
                            }
                        }

                        produtos.RemoveAll(p => p.IdProduto.Equals(idProduto));
                        CarregaGridProdutos();
                        AtualizaEstoque();
                        CalculaTotal();

                        MessageBox.Show("Produto removido com sucesso.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception)
                    {
                        MessageBox.Show(Properties.Resources.ErroConsultaDados);
                    }
                }
            }
        }

        #endregion

        #region Metódos

        private void AtualizaDetalhesProdutos()
        {
            Produtos produto = (Produtos)cbProdutos.SelectedItem;
            lbProduto.Text = produto.NomeProduto;
            lbPreco.Text = produto.PrecoVenda.ToString("C");
        }

        private void CarregaComboProdutos()
        {
            List<Produtos> produtos = ProdutosDAO.GetAllProdutos();

            if (produtos.Count > 0)
            {
                cbProdutos.DataSource = produtos;
                cbProdutos.ValueMember = "IdProduto";
                cbProdutos.DisplayMember = "NomeProduto";
            }
            else
            {
                btnAdicionar.Enabled = false;
                btnFecharPedido.Enabled = false;
                gbDetalhesProduto.Visible = false;
                MessageBox.Show("Nenhum produto cadastrado!", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void CarregaGridProdutos()
        {
            // botao deletar
            if (!gvProdutos.Columns.Contains("btnDelete"))
            {
                DataGridViewImageColumn btnDeleteLinha = new DataGridViewImageColumn();
                btnDeleteLinha.HeaderText = "Excluir";
                btnDeleteLinha.Name = "btnDelete";
                btnDeleteLinha.Width = 70;
                btnDeleteLinha.Image = Properties.Resources.DeleteImage;
                gvProdutos.Columns.Add(btnDeleteLinha);
            }

            gvProdutos.DataSource = null;
            gvProdutos.DataSource = produtos;

            gvProdutos.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

            gvProdutos.Columns["IdProduto"].HeaderText = "Código";
            gvProdutos.Columns["NomeProduto"].HeaderText = "Produto";
            gvProdutos.Columns["QuantidadeProduto"].HeaderText = "Quantidade";
            gvProdutos.Columns["PrecoVenda"].HeaderText = "Preço";

            gvProdutos.Columns["NomeProduto"].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            gvProdutos.ColumnHeadersDefaultCellStyle.Font = new Font("Arial", 10, FontStyle.Bold);
            gvProdutos.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter;
            gvProdutos.DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter;
            gvProdutos.DefaultCellStyle.Font = new Font("Arial", 10, FontStyle.Regular);

            gvProdutos.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            gvProdutos.Columns["PrecoVenda"].DefaultCellStyle.Format = "C";
        }

        private int GetQuantidade()
        {
            int quantidade = 0;

            foreach (var item in produtos)
            {
                quantidade += item.QuantidadeProduto;
            }

            return quantidade;
        }

        private decimal GetTotal()
        {
            decimal total = 0;

            foreach (var item in produtos)
            {
                total += item.PrecoVenda;
            }

            return total;
        }

        private void CalculaTotal()
        {
            decimal total = 0;

            foreach (var item in produtos)
            {
                total += item.PrecoVenda;
            }

            lbTotal.Text = "TOTAL: " + total.ToString("C");
            lbTotal.Visible = true;
        }

        /// <summary>
        /// ATUALIZA O TEXTO DO ESTOQUE
        /// </summary>
        private void AtualizaEstoque()
        {
            txtEstoque.Text = (cbProdutos.SelectedItem as Produtos).QuantidadeProduto.ToString();
        }

        private void RecarregaTela()
        {
            CarregaComboProdutos();
            LimpaGridViewProdutos();
            LimpaCampos();
        }

        private void LimpaGridViewProdutos()
        {
            produtos.Clear();
            CarregaGridProdutos();
        }

        private void LimpaCampos()
        {
            txtQuantidade.Text = string.Empty;
            lbTotal.Visible = false;
        }

        #endregion

        #region Validações

        /// <summary>
        /// Usa os métodos de validação e valida todo o formulário
        /// </summary>
        /// <returns></returns>
        private bool ValidaCampos()
        {
            bool nomeProduto = ValidaNomeProduto();
            bool quantidade = ValidaQuantidade();

            if (!nomeProduto)
                cbProdutos.Focus();
            else if (!quantidade)
                txtQuantidade.Focus();

            return nomeProduto && quantidade;
        }

        /// <summary>
        /// Método que válida o campo NomeProduto
        /// </summary>
        /// <returns>retorna true se for válido e false se for inválido</returns>
        private bool ValidaNomeProduto()
        {
            bool valido = false;

            if (cbProdutos.SelectedItem == null)
            {
                gbDetalhesProduto.Visible = false;
                epProduto.SetError(cbProdutos, "O campo Produto é obrigatório.");
            }
            else
            {
                epProduto.Clear();
                valido = true;
            }

            return valido;
        }
        //********************************************************************************************************************************
        /// <summary>
        /// Método que válida o campo Quantidade
        /// </summary>
        /// <returns>retorna true se for válido e false se for inválido</returns>
        private bool ValidaQuantidade()
        {
            bool valido = false;
            int res;

            if (txtQuantidade.Text == string.Empty)
            {
                epQuantidade.SetError(txtQuantidade, "O campo Quantidade é obrigatório.");
            }
            else if (!Int32.TryParse(txtQuantidade.Text, out res))
            {
                epQuantidade.SetError(txtQuantidade, "O campo Quantidade deve ser preenchido apenas com números.");
                txtQuantidade.Text = string.Empty;
            }
            else
            {
                epQuantidade.Clear();
                valido = true;
            }

            return valido;
        }

        #endregion
    }
}
